
#include "DevModbusDeal.h"
#include "GDDevBase.h"
#include "ProtocolSwitch.h"
#include "DevRecode.h"
#include "ProxyUnit_DL645.h"
#include "Comm.h"
#include "util.h"
#include "LocalCom2.h"
#include "DevRecode.h"

COMM_CTRL_TYPE PLCCom; 


Dlt645_Inverter_Type PLCResData;        //645转发的应答报文
Send_Inverter_Frame_Type invSendFrame;	//PLC给到逆变器的数据参数

All_Dev_Send_Frame g_allDevSendFrame;	//PLC给到所有逆变器或所有开关的数据参数

Dl645_Vari_Type Port_Vari[COMDRV_PORT_MAX]; 

Dev_Recode_Type g_InverterDevfile[inverterDEVMax]; 


Intermediate_Frame_Type   intermediateDev[inverterDEVMax];      //中间层参数，例如百分比调节功率，是按照645发的百分比是按实际百分比调节的功率

Reg_Bank g_reg_bank[MAX_REG_BANK_COUNT]; //存储所有厂家所有版本的寄存器点表


#define Inverter_STACK_SIZE 0x2000
#define Inverter_PRIORITY 27


// ============================================================================
// Function name: 	Dlt645_MakeRtnFrame
// Description:	发送帧打包组帧
// Input:			*pUartBuf
// Output:		Null
// ============================================================================
u8 Dlt645_MakeRtnFrame(Dlt645_Frame_Type *pUartBuf, u8 port)
{
	u8 i,nTxByte;
	
	// 取通信地址
	memcpy(&pUartBuf->head.adr[0], g_Dlt645Para.CommunicateAddr, FRAME_ADDRLENGTH);
	//处理写后续帧和无后续帧，协议没有区别，应答保持一致
	if(pUartBuf->head.ctl==Dl645_WriteData_Subsequent)
	pUartBuf->head.ctl=Dl645_WriteData_2007;

	pUartBuf->head.ctl |= BIT7;									// 置接收帧响应控制字标志位
	
	for (i = 0; i < pUartBuf->head.len; i++)							// 数据域 +0x33
	{
		pUartBuf->data[i] += 0x33;
	}
	// 校验码
	pUartBuf->data[FRAME_SUM_INDEX(pUartBuf)] = CalChkSum((u8 *)pUartBuf, pUartBuf->head.len + FRAME_HEAD_SIZE);
	// 结束码
	pUartBuf->data[FRAME_EOF_INDEX(pUartBuf)] = FRAME_EOF;
	// 生成帧发送字节数
	nTxByte = FRAME_LENGTH(pUartBuf);
	// 添加前导字节0xFE
	memmove(((u8 *)pUartBuf)+DLT645PROC_RTN_FENUMS, (u8 *)pUartBuf, nTxByte);
	memset((u8 *)pUartBuf, 0xFE, DLT645PROC_RTN_FENUMS);
	nTxByte += DLT645PROC_RTN_FENUMS;
	
	return nTxByte;
}

// ============================================================================
// Function name: 	Dlt645_SendRtnFrame
// Description:	返回正确帧信息
// Input:			*pUartBuf, *pUartVari
// Output:		Null
// ============================================================================
void Dlt645_SendRightRtnFrame(Dlt645_Frame_Type *pUartBuf, Dl645_Vari_Type *pUartVari, u8 port)
{
	u8 nTxByte;

	// 清错误状态字
	Dl645_Public.Error = 0;
	
	// 取通信数据长度
	nTxByte = pUartVari->Protocol.nBytes;
	if(pUartBuf->head.ctl == Dl645_ReadSequentData_2007)			// 读后续帧处理,填充后续帧帧序号			
	{
		pUartBuf->data[nTxByte] = pUartVari->Sequent.FrameNo++;	
		nTxByte += 1;
	}
	pUartBuf->head.len = nTxByte;

	// 读到的数据帧有无后续帧标志
	if (pUartVari->Sequent.fSingleDI | pUartVari->Sequent.fBlockDI)
	{
		{pUartBuf->head.ctl |= BIT5;}
	} 			
	else
		{pUartVari->Sequent.FrameNo = 1;}
	if(pUartVari->Sequent.FrameNo == 0)
		{pUartVari->Sequent.FrameNo = 1;}
		
	// 填充UART需要发送字节数
	pUartVari->Protocol.nBytes = Dlt645_MakeRtnFrame(pUartBuf, port);

	return;	
}

// ========================================================================================
// Function name: *Uart1_Hard_GetVara
// Description:	
// Input:			NULL
// Output:		
// ========================================================================================
Dl645_Vari_Type *Dlt645_GetPortVari(u8 PortNO)
{
	if (PortNO >= COMDRV_PORT_MAX)
        PortNO = COM_PORT_LOCAL_COM1;

	return &Port_Vari[PortNO];
}

u8 getDataRd(u8 *DataBuf,u8* rxData)
{
    Dl645_Vari_Type *pUartVari; 
	u8 Bytelen=0;

	if((invSendFrame.regsHaveSendSize + invSendFrame.regsNextSendSize) >= invSendFrame.regsSize)//可以打包  //new
	{
			Bytelen=CheckDevFunNew(DataBuf,rxData); 
			if(Bytelen==no_resp_645)
			{
				invSendFrame.SendTicker = TickerStart();
				return no_resp_645;
			}
			else if(Bytelen!=0)
			{
				responseModbus.data_len=4+Bytelen;
				invSendFrame.SendTicker = TickerStart();
				return true;
			}
			else
			{
				return false;
			}
			
	}
	else
	{

		Bytelen+=CheckDevFunNew(DataBuf,rxData);
		invSendFrame.SendTicker = TickerStart();
		invSendFrame.status=ReceModbus;
		SendMessageDeal();
		
	}	
	return false;
	


}

// ============================================================================
// Function name: 	Dlt645_SendRtnFrame
// Description:	返回错误帧信息
// Input:			*pUartBuf, *pUartVari
// Output:		Null
// ============================================================================
void Dlt645_SendErrorRtnFrame(Dlt645_Frame_Type *pUartBuf, Dl645_Vari_Type *pUartVari, u8 port)
{
    // 置其他错误信息位
    if(!(Dl645_Public.Error & 0x7E)) {
        Dl645_Public.Error = BIT0;
    }
    pUartBuf->data[0] = Dl645_Public.Error;
    pUartBuf->head.len = 1;

	pUartBuf->head.ctl |= BIT6;						// 控制字中的异常应答位
	// 清UART相关变量
	memset(pUartVari,0,sizeof(Dl645_Vari_Type));
	pUartVari->Protocol.nBytes = Dlt645_MakeRtnFrame(pUartBuf, port);	

	return;
}





void ByteSwap(uint8_t *data, uint8_t len)
{
    if (data == NULL || (len != 2 && len != 4 && len != 8)) {
        return; // 仅支持 2/4/8 字节的转换
    }

    if (len == 2) {
        uint8_t temp = data[0];
        data[0] = data[1];
        data[1] = temp;
    }
}


u8 checkRecWrite(u8 *pRxBuf)
{
	
		if (invSendFrame.regsHaveSendSize + invSendFrame.regsNextSendSize >= invSendFrame.regsSize){
			return true;
		}else{//尚未接收完成
			//复制发送队列的数据到已经发送的数据队列里面
			for (int i = 0; i < invSendFrame.regsNextSendSize; i++){
				invSendFrame.regsHaveSend[invSendFrame.regsHaveSendSize++] = invSendFrame.regsNextSend[i];
			}
			invSendFrame.regsNextSendSize = 0;

			SendMessageDeal();
			invSendFrame.SendTicker = TickerStart();
		}
	return false;

}

/**
 * @brief 使用逐位计算法计算CRC16
 * @param pData 数据指针
 * @param iLen 数据长度
 * @return CRC16校验码
 */
uint16_t CRC16_Modbus_Bitwise(const uint8_t *pData, int iLen)
{
    uint16_t wCRC = 0xFFFF; // 初始值
    for (int i = 0; i < iLen; i++) {
        wCRC ^= pData[i]; // 当前字节与CRC低8位异或
        for (int j = 0; j < 8; j++) { // 处理每个字节的8个bit
            if (wCRC & 0x0001) {     // 检查最低位是否为1
                wCRC = (wCRC >> 1) ^ 0xA001; // 右移并与多项式异或
            } else {
                wCRC = wCRC >> 1; // 只需右移
            }
        }
    }
    return wCRC;
}


u16 ProModbusMT_MakeFrm_UniRd(u8 MBAddr, u8 fc, u16 RegAddr, u16 RegNum, u8 *txBuf, u8 crcRevFlag)
{
	u16 crc;
	
	txBuf[0] = MBAddr;					// 通信地址
	txBuf[1] = fc;						// 功能码
	txBuf[2] = (RegAddr>>8);			// 起始寄存器地址高字节
    txBuf[3] = RegAddr;                 // 起始寄存器地址低字节
	txBuf[4] = (RegNum>>8);				// 起始寄存器地址高字节
	txBuf[5] = RegNum;					// 起始寄存器地址低字节
	crc = CRC16_Modbus_Bitwise(txBuf, 6);
	if (crcRevFlag == 0)
		ByteSwap((u8 *)&crc, 2);
	txBuf[6] = crc >> 8;
	txBuf[7] = crc;
	return 8;
}


// ========================================================================================
// 描  述 : 地址检查 MQTT匹配
//          注意:入口的所有reg的data数据，必须已经是符合modbus的高字节在前的顺序
// 输  入 : rxedAddr：装置地址
// 输  出 : None
// 返回值 : 匹配地址返回1，广播地址返回2，非法地址返回0
// ========================================================================================
u8 ProModbusMqtt_IsAddrOK(u8 rxedAddr)
{	
	// if (rxedAddr == g_ModbusPara.siteid)//不能是本地地址，等于透传+处理
	// 	return 0;
	if (rxedAddr>0&&rxedAddr<254)//后续加个循环一次配置
		return 1;
	if (rxedAddr == PROTC_MODBUSMT_BROADADDR)
		return 0;
	return 0;
}

// ========================================================================================
// 描  述 : 协议解析，数据合法性判断
//          当前判断校验位和各功能码的帧长合法性
// 输  入 : *rxData：接收到的数据缓冲区
//          rxLen：接收到的数据长度
// 输  出 : None
// 返回值 : false：数据不合法  true：数据合法
// ========================================================================================
u8 ProModbusMqtt_IsFrmOK(u8 *rxData, u16 rxLen)
{
	u8 fc;
	// 最短帧长限制
	if (rxLen <= 4)
		return false;
	// 帧校验
	if (CRC16_Modbus_Bitwise(rxData, rxLen-2) != LoadInt32(&rxData[rxLen-2]))
		return false;

	return true;
}


// ========================================================================================
// 描  述 : 协议解析MODbus逆变器数据，地址不是本地地址
//          不检查应答帧是否是所需要的应答帧，只解析，获取有用数据
// 输  入 : *rxData：接收数据缓冲区 
//          rxLen：接收数据长度
//          *txData：发送数据缓冲区
//          txLen：发送数据长度
// 输  出 : None
// 返回值 : false：非本协议  true：协议正确处理
// ========================================================================================
u8  ProModbusInver_UnpackFrm(COMM_CTRL_TYPE *pCommCtrl)
{
	u8 sendFlag;

	if (ProModbusMqtt_IsFrmOK(pCommCtrl->pRxBuf, pCommCtrl->RxedLen) == false)	
	return false;
	// 地址检查
	if(ProModbusMqtt_IsAddrOK(pCommCtrl->pRxBuf[0])==0)
	return false;
	// 预置为无应答 
	pCommCtrl->TxLen = 0; 
	if(invSendFrame.status!=ReceModbus)
	return false;


		//读
		if(invSendFrame.curFuncType==read)
		{
			u8 test[10];
			pCommCtrl->pRxBuf+=3;
			sendFlag=getDataRd((u8 *)&(responseModbus.data[4]),pCommCtrl->pRxBuf);//获取读数据的参数
			if(sendFlag==true)
			{
				respone_645_frame(&responseModbus, true);
				invSendFrame.status=Receok;
			}
			else if(sendFlag==no_resp_645)
			{
				invSendFrame.status=Receok;
			}
		}
		//写
		else if(invSendFrame.curFuncType==write)
		{
			if(checkRecWrite(pCommCtrl->pRxBuf)==true)
			{
				if(invSendFrame.status==ReceModbus)
				{
					if(invSendFrame.recflag==true)
					{
						respone_645_frame(&responseModbus, true);
					}
					invSendFrame.status=Receok;
					invSendFrame.SendTicker = TickerStart(); //更新时间
				}
			}
		}

	return true;
}

// =====================================================================================
// 协议打包通用写发送帧(仅支持fc=5,6,15,16),返回帧长 
// 标准modbus下crcRevFlag=0
// wrData:比如要写两个寄存器，第一个为0x1234，第二个为0x5678，则wrdata=0x12,0x34,0x56,0x78
// =====================================================================================
u16 ProModbusMT_MakeFrm_UniWr(u8 MBAddr, u8 fc, u16 RegAddr, u16 RegNum, u8 *txBuf, u8 *wrData, u8 crcRevFlag)
{
	u16 crc, i, dataLen;
	
	txBuf[0] = MBAddr;					// 通信地址
	txBuf[1] = fc;						// 功能码
	txBuf[2] = (RegAddr>>8);			// 起始寄存器地址高字节
	txBuf[3] = RegAddr;					// 起始寄存器地址低字节
	if ((fc == MODBUS_FC_WCOIL) || (fc == MODBUS_FC_WRSREG))
	{// 写单个寄存器
		txBuf[4] = wrData[0];			// 要写入的数据
		txBuf[5] = wrData[1];			// 要写入的数据字节数
		crc = CRC16_Modbus_Bitwise(txBuf, 6);
		if (crcRevFlag == 1)
			ByteSwap((u8 *)&crc, 2);
		txBuf[6] = crc >> 8;
		txBuf[7] = crc;
		return 8;
	}
	else if ((fc == MODBUS_FC_WRMCOIL) || (fc == MODBUS_FC_WRMREG))
	{// 写多个寄存器
		txBuf[4] = (RegNum>>8); 		// 寄存器个数高字节
		txBuf[5] = RegNum;				// 寄存器个数低字节
		dataLen = RegNum*2;
		txBuf[6] = dataLen;				// 要写入的数据字节数
		for (i = 0; i < dataLen; i++)
		{
			txBuf[7+i] = wrData[i];	
		}
		crc = CRC16_Modbus_Bitwise(txBuf, 7+dataLen);
		if (crcRevFlag == 1)
			ByteSwap((u8 *)&crc, 2);
		txBuf[7+dataLen] = crc >> 8;
		txBuf[8+dataLen] = crc;
		return (9+dataLen);
	}
	else
		return 0;
}

void sendModbusWr(u8 port,u8 Addr,u16 RegAddr,u8 RegNum,u8 FunCode,u8* wrData)
{
    u8 txbuf[255]={0};
    u8 txlen;
	txlen=ProModbusMT_MakeFrm_UniWr(Addr,FunCode,RegAddr,RegNum,txbuf,wrData,0);
    usart6_send_data_it(txbuf, txlen);
}


void sendModbusRd(u8 port,u8 Addr,u16 RegAddr,u8 RegNum,u8 FunCode)
{
    u8 txbuf[255]={0};
    u8 txlen;
    txlen=ProModbusMT_MakeFrm_UniRd(Addr,FunCode,RegAddr,RegNum, txbuf,0);
    usart6_send_data_it(txbuf, txlen);
}

 //bin转数组的形式，长度4的后续再看
void binToArryBig(u32 val,u8*Arry,u8 len)
{
    if (len == 1)
    {
        Arry[1]=val&0xff;
    }
    else if (len == 2)
    {
		 memrcpy(Arry, (u8*)&(val), 2);
    }
    else if (len == 4)
    {
        memrcpy(Arry, (u8*)&(val), 4);
    }
}



Dev_Recode_Type chooseDev(u8 devNum)  
{
	Dev_Recode_Type devData;
	devData.addr=3;
	memcpy(devData.manufacturer,manufactureritems[0],32);
	devData.version=7;
	devData.devType=DEV_INV; 
	return devData;
}


void InsertAndSortActiveReg_rd(Reg_Bank* regbank, u8 regIndex)
{
    // 如果缓存没有数据，直接插入
	if (invSendFrame.regsSize <= 0) {
		invSendFrame.regs[0].reg_flag = regIndex;
		invSendFrame.regs[0].functype = read;
		invSendFrame.regsSize++;
		return;
	}

	// 查找插入位置
    int i = invSendFrame.regsSize - 1; // 从末尾开始遍历
    while (i >= 0 && regbank->regs[invSendFrame.regs[i].reg_flag].addr > regbank->regs[regIndex].addr)
    { // 比regIndex的地址大的元素后移

        invSendFrame.regs[i + 1].reg_flag = invSendFrame.regs[i].reg_flag;//下标替换
        invSendFrame.regs[i + 1].functype = invSendFrame.regs[i].functype;
        i--;
    }

	
    // 插入regIndex
    invSendFrame.regs[i + 1].reg_flag= regIndex;
	invSendFrame.regs[i + 1].functype= read;
	invSendFrame.regsSize++;
}


void InsertAndSortActiveReg_wr(Reg_Bank* regbank, Reg_Send_Info regIndex) {
	
	// 如果缓存没有数据，直接插入
	if (invSendFrame.regsSize <= 0) {
		invSendFrame.regs[0].reg_flag = regIndex.reg_flag;
		invSendFrame.regs[0].functype = regIndex.functype;
		invSendFrame.regsSize++;
		return;
	}
	
    // 插入regIndex
    invSendFrame.regs[invSendFrame.regsSize].reg_flag= regIndex.reg_flag;
	invSendFrame.regs[invSendFrame.regsSize].functype= regIndex.functype;
	invSendFrame.regsSize++;
}

//查找对应的寄存器点表
Reg_Bank* FindRegBank(Dev_Recode_Type *archive	)
{
	return (Reg_Bank*)&g_reg_bank[0];

}

// 插入发送缓存的寄存器中读
bool insertSendRegCache_rd(Dev_Recode_Type *archive, u8 *pRegArray, u16 size)
{
	s8 allPagNullFlag=inValidFlag;	
	Reg_Bank * regbank = (Reg_Bank *)&g_reg_bank[0];

	
	if (regbank)
	{
		invSendFrame.regsSize = 0; //清空发送缓存
		
		for(u16 i = 0; i < size; i++)
		{
			if(regbank->regs[pRegArray[i]].flag==vaildFlag)
			{
				allPagNullFlag=vaildFlag;
			}
			InsertAndSortActiveReg_rd(regbank, pRegArray[i]); //插入寄存器到发送缓存队列中
			invSendFrame.regValue[pRegArray[i]].len = 0; //缓存寄存器值清零
		}

		//已发送和下次发送缓存清零 
		invSendFrame.regsHaveSendSize = 0;
		invSendFrame.regsNextSendSize = 0;
		if(allPagNullFlag==inValidFlag)
        {
			return 	false;
		} 
		return true; 
		 
	}
	else if(regbank==NULL)
	{
		printf("regbank==Null\n");
	}
	return false;
} 
 
//插入发送缓存的寄存器中写
u8 insertSendRegCache_wr(Dev_Recode_Type *archive, Reg_Send_Info *pRegArray, u16 size)
{
	Reg_Bank * regbank = FindRegBank(archive); //查找对应厂家对应版本的寄存器点表
	
	if (regbank)
	{
		invSendFrame.regsSize = 0; //清空发送缓存
		for(u16 i = 0; i < size; i++)
		{
			if(regbank->regs[pRegArray[i].reg_flag].flag==vaildFlag)
			
			InsertAndSortActiveReg_wr(regbank, pRegArray[i]); //插入寄存器到发送缓存队列中

			invSendFrame.regValue[pRegArray[i].reg_flag].len = 0; //缓存寄存器值清零
		}

		//已发送和下次发送缓存清零 
		invSendFrame.regsHaveSendSize = 0;
		invSendFrame.regsNextSendSize = 0;

		return true;
		
	}
	return false;
}


s8 SendMessageDeal()
{
	u8 	port;
	u8 	addr;
	u16 regaddr;
	u8 	regNum;
	u8	fc;

	u8 wribuf[255];
	Get_Frame_Type getFrame;

	getFrame=getSendDate(invSendFrame.typeItem,wribuf);
	
	if(getFrame.regNum == 0) //没有需要发送的寄存器,在这里需要处理返回plc指令
        return -1;

	port=invSendFrame.dv.port;
	addr=invSendFrame.dv.addr;
	regaddr=getFrame.regAddr-1;
	regNum=getFrame.regNum;
	fc=getFrame.fc;

	if(invSendFrame.curFuncType==read)
	{ 
		sendModbusRd(port,addr,regaddr,regNum,fc);
	}
	else if(invSendFrame.curFuncType==write)
	{
		sendModbusWr(port,addr,regaddr,regNum,fc,wribuf);
	}
	
	return 1;
}

void InsertAndSortActiveRegForAllDev_rd(Send_Inverter_Frame_Type *frame, Reg_Bank* regbank, u8 regIndex)
{
    // 如果缓存没有数据，直接插入
	if (frame->regsSize <= 0) {
		frame->regs[0].reg_flag = regIndex;
		frame->regs[0].functype = read;
		frame->regsSize++;
		return;
	}

	// 查找插入位置
    int i = frame->regsSize - 1; // 从末尾开始遍历
	while (i >= 0 && regbank->regs[frame->regs[i].reg_flag].addr > regbank->regs[regIndex].addr) 
    {
        // 比regIndex的地址大的元素后移
		frame->regs[i + 1].reg_flag = frame->regs[i].reg_flag;//下标替换
		frame->regs[i + 1].functype = frame->regs[i].functype;
		i--;
	}

    // 插入regIndex
    frame->regs[i + 1].reg_flag= regIndex;
	frame->regs[i + 1].functype= read;
	frame->regsSize++;
}

void InsertAndSortActiveRegForAllDev_wr(Send_Inverter_Frame_Type *frame,  Reg_Bank* regbank, Reg_Send_Info regIndex)
{
// 如果缓存没有数据，直接插入
	if (frame->regsSize <= 0) {
		frame->regs[0].reg_flag = regIndex.reg_flag;
		frame->regs[0].functype = regIndex.functype;
		frame->regsSize++;
		return;
	}
	
    // 插入regIndex
    frame->regs[frame->regsSize].reg_flag= regIndex.reg_flag;
	frame->regs[frame->regsSize].functype= regIndex.functype;
	frame->regsSize++;
}

u8 insertSendRegCacheForAllDev_wr(Send_Inverter_Frame_Type *frame,  Dev_Recode_Type *archive, Reg_Send_Info *pRegArray,u16 size)
{
	Reg_Bank * regbank = FindRegBank(archive); //查找对应厂家对应版本的寄存器点表
	
	if (regbank)
	{
		frame->regsSize = 0; //清空发送缓存
		for(u16 i = 0; i < size; i++)
		{
			if(regbank->regs[pRegArray[i].reg_flag].flag==vaildFlag)
			
			InsertAndSortActiveRegForAllDev_wr(frame, regbank, pRegArray[i]); //插入寄存器到发送缓存队列中

			frame->regValue[pRegArray[i].reg_flag].len = 0; //缓存寄存器值清零
		}

		//已发送和下次发送缓存清零 
		frame->regsHaveSendSize = 0;
		frame->regsNextSendSize = 0;

		return true;
		
	}
	return false;
}

u8 insertSendRegCacheForAllDev_rd(Send_Inverter_Frame_Type *frame,  Dev_Recode_Type *archive, u8 *pRegArray, u16 size)
{
	s8 allPagNullFlag=inValidFlag;
	
	Reg_Bank * regbank = FindRegBank(archive); //查找对应厂家对应版本的寄存器点表
	if (regbank)
	{
		frame->regsSize = 0; //清空发送缓存
		
		for(u16 i = 0; i < size; i++)
		{
			if(regbank->regs[pRegArray[i]].flag==vaildFlag)
			{
				allPagNullFlag=vaildFlag;
			}
			InsertAndSortActiveRegForAllDev_rd(frame, regbank, pRegArray[i]); //插入寄存器到发送缓存队列中
			frame->regValue[pRegArray[i]].len = 0; //缓存寄存器值清零
		}

		//已发送和下次发送缓存清零 
		frame->regsHaveSendSize = 0;
		frame->regsNextSendSize = 0;
		if(allPagNullFlag==inValidFlag)
		{
			return 	inValidFlag;
		} 
		return true; 
		 
	}
	else if(regbank==NULL)
	{
		printf("insertSendRegCacheForAllDev_rd regbank==Null\n");
	}
	return false;
}


// 准备发送下一个设备帧 
/*
*需要考虑下超时的情况，超时的设备需要用0xff来替代值还是直接回应645错误?
*/
bool sendNextDevFrame()
{
	bool findNextDev = false;
	//循环获取需要下发的设备
	for (int i = g_allDevSendFrame.frameIndex+1; i < g_allDevSendFrame.frameCount; i++) 
	{
		g_allDevSendFrame.frameIndex = i; //更新下一个需要发送的设备帧索引
		//如果状态为发送状态StartSend而且缓存数据未发送则视为下一个需要发送的设备帧
		if (StartSend == g_allDevSendFrame.frame[i].status &&  
			g_allDevSendFrame.frame[i].regsSize > 0 &&
			g_allDevSendFrame.frame[i].regsHaveSendSize == 0) 
		{
			invSendFrame = g_allDevSendFrame.frame[i];
			findNextDev = true;
			break;
		}
	}
	invSendFrame.SendTicker = TickerStart();
	if (findNextDev) // 找到下一个设备帧，准备发送该设备帧
	{
		invSendFrame.status=ReceModbus;
		SendMessageDeal();
		return true;
	}
	return false;
}

void Inverter_StepDo(void)
{
	switch (invSendFrame.status)
	{
			case StartSend:
			{
				s8 status;
				status=SendMessageDeal();
				if(status==-1)
				{
					printf("dealFaild\n");
					invSendFrame.status=dealFaild;
				}
				else 
				{
					printf("ReceModbus\n");
					invSendFrame.SendTicker = TickerStart();
					invSendFrame.status=ReceModbus;
				}
			break;
			}
				
			case ReceModbus:
			{
				if (TickerOut(invSendFrame.SendTicker, MS2TICKS(6000)) == true)		// 发送到接受数据要在400ms内
				{
					invSendFrame.status=tickOut;
				}
				break;
			}

			case tickOut://超时
			{
				printf("tickOut\n");
				invSendFrame.status=dealFaild;
			}
			break;
			case Receok:
			{
				invSendFrame.status=Waiting;
				break;
			}
				
			
			case dealFaild:
				printf("dealFaild\n");
				invSendFrame.status=Waiting;
			break;
			default:
			break;
		}	
}

void* Inverter_TaskMain(void* arg)
{
	invSendFrame.status=Waiting;
	 /**
     * 配置逆变器的档案，如需支持更多的逆变器，可以参看增加
     */
    Inv_agmtDeal();
	
	while (1)
	{
		Inverter_StepDo();
		LOS_TaskDelay(200);
	}
	
}

void Inverter_Service(void)
{
    UINT32 ret;
    UINT32 taskID1;
    TSK_INIT_PARAM_S stTask = {0};

    printf("Inverter Service starting...\n");
    stTask.pfnTaskEntry = (TSK_ENTRY_FUNC)Inverter_TaskMain;
    stTask.uwStackSize = Inverter_STACK_SIZE;
    stTask.pcName = "Inverter_Task";
    stTask.usTaskPrio = Inverter_PRIORITY;
    ret = LOS_TaskCreate(&taskID1, &stTask);
    if (ret != LOS_OK) {
        printf("Inverterservice failed\n");
    }
}


SYS_RUN(Inverter_Service);
